import Cesium from '../Ces/Cesium';
import WeDisplayShaders from './WeDisplayShaders';

export const vsSource = `
    ${Cesium._shadersPolylineCommon}
  ${WeDisplayShaders.WeCartesian3FromRadians}

  uniform float extrusionHeight;
  uniform sampler2D u_particlesTexture;
  out vec3 v_color;
  out vec2 v_st;

  vec3 getPointStr(float pointId,float lineId) {
    float bufferSize = Weget_bufferSize();
    float pointIdC = floor(mod(pointId,bufferSize));
    vec2 st = vec2(pointIdC,lineId) / (bufferSize - 1.0);
    return texture(u_particlesTexture,st).rgb;
  }

  vec3 getWorldPosition(vec3 LLH) {
    if(LLH == vec3(0.0))
    {
      return LLH;
    }

    vec4 localExtent = Weget_localExtent();
    LLH.xy = WeGetImageryLonLat(LLH.xy,localExtent);

    float scaleZ = Weget_scaleZ();
    float extrusion = Weget_extrusion();
    LLH.z *= extrusion * scaleZ;

    return we_cartesian3FromRadians(LLH);
  }

  vec4 getClipPositionWC(float pointId,float lineId,out vec3 str){
    str = getPointStr(pointId,lineId);
    vec3 currentWorldCoords = getWorldPosition(str);
    vec3 currentEC = (czm_modelView * vec4(currentWorldCoords,1.0)).xyz;

    vec3 nextWorldCoords = getWorldPosition(getPointStr(pointId + 1.0,lineId));
    vec3 nextEC = (czm_modelView * vec4(nextWorldCoords,1.0)).xyz;

    bool segmentClipped, segmentCulled;
    vec4 clippedPositionWC, clippedPositionEC;
    clipLineSegmentToNearPlane(currentEC, nextEC.xyz,
      clippedPositionWC, segmentClipped, segmentCulled, clippedPositionEC);

    if(segmentClipped || segmentCulled){
      return vec4(0.0);
    }

    return vec4(clippedPositionWC.xyz,(czm_projection * clippedPositionEC).w);
  }

  vec2 getDirectionToNextRight(vec4 clippedPositionWC0,vec4 clippedPositionWC1)
  {
    vec2 directionToNextWC = normalize(clippedPositionWC0.xy - clippedPositionWC1.xy);
    return vec2(directionToNextWC.y, -directionToNextWC.x);
  }

  void main()
  {
      float pointSize = Weget_pointSize();
      float bufferSize = Weget_bufferSize();
      float vertexId = float(gl_VertexID);

      float numPointOfLine = 2.0 * bufferSize;
      float lineId = floor(vertexId/numPointOfLine);
      float pointId = floor(mod(vertexId,numPointOfLine));
      float pointIdR = floor(pointId/bufferSize);
      float pointIdC = floor(mod(pointId,bufferSize));

      vec3 str0,str1;

      vec4 clippedPositionWC0 = getClipPositionWC(pointId,lineId,str0);
      vec4 clippedPositionWC1 = getClipPositionWC(pointId + 1.0,lineId,str1);

      vec2 directionToNextRight = getDirectionToNextRight(clippedPositionWC0,clippedPositionWC1);

      float visible = 1.0;
      if(clippedPositionWC0 == vec4(0.0))
      {
        visible = 0.0;
        return;
      }

      directionToNextRight *= pointSize * 0.5;
      if(pointIdR == 1.0)
      {
        directionToNextRight *= -1.0;
      }
      vec4 clippedPositionWC = clippedPositionWC0;

      vec4 positionWC = vec4(clippedPositionWC.xy + directionToNextRight * czm_pixelRatio, clippedPositionWC.z, 1.0)
        * clippedPositionWC.w;

      gl_Position = czm_viewportOrthographic * positionWC;
      gl_Position *= visible;
      gl_PointSize = pointSize * czm_pixelRatio;
      v_color = vec3(1.0);
      v_st = vec2(pointIdC/(bufferSize - 1.0),pointIdR);
  }
`

export const fsSource = `
  in vec3 v_color;
  in vec2 v_st;
  void main()
  {
    vec2 st = v_st;
    vec4 outlineColor = Weget_outlineColor();
    vec4 color = vec4(v_color,1.0);
    float outlineWidth = Weget_outlineWidth();

    float v_width = Weget_pointSize();
    float halfInteriorWidth =  0.5 * (v_width - outlineWidth) / v_width;
    float b = step(0.5 - halfInteriorWidth, st.t);
    b *= 1.0 - step(0.5 + halfInteriorWidth, st.t);

    // Find the distance from the closest separator (region between two colors)
    float d1 = abs(st.t - (0.5 - halfInteriorWidth));
    float d2 = abs(st.t - (0.5 + halfInteriorWidth));
    float dist = min(d1, d2);

    vec4 currentColor = mix(outlineColor, color, b);
    vec4 outColor = czm_antialias(outlineColor, color, currentColor, dist);
    outColor = czm_gammaCorrect(outColor);

    color = outColor;

    out_FragColor = color;
  }
`


export default {}
